home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_C
/
XBITMAP_
/
XBITMAP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-21
|
18KB
|
767 lines
/*
* Program to convert X11 Bitmap files to Macintosh 'PICT' files,
* and vice versa. Also useful as a viewer.
*
* This source code is hereby placed into the public domain.
*
* Earle R. Horton Friday, March 10, 1989
*/
#include <Stdio.h>
#include <Quickdraw.h>
#include <Menus.h>
#include <Windows.h>
#include <Events.h>
#include <Controls.h>
#include <Dialogs.h>
#include <Fonts.h>
#include <Desk.h>
#include <Files.h>
#include <Memory.h>
#include <Packages.h>
#include <Resources.h>
#include <Errors.h>
#ifndef TRUE
#define TRUE (-1)
#define FALSE 0
#endif
#ifdef macintosh
#include <compat.h>
#endif
#define lastMenu 3
#define appleMenu 1
#define fileMenu 256
#define editMenu 257
#define openX 1
#define openPICT 2
#define openPNTG 3
#define saveX 5
#define savePICT 6
#define savePNTG 7
#define Quit 9
MenuHandle myMenu[lastMenu];
Rect dragRect, pRect;
EventRecord myEvent;
int refNum, MyControl, doneFlag;
int scale, code;
WindowRecord wRecord;
WindowPtr theWindow, whichWindow;
char *icons[6][48];
ControlHandle hScroll, vScroll, whichControl;
Point theOrigin;
RgnHandle theUpdateRgn;
Handle XCursor;
GrafPort srcport;
DieGraceFully()
{
exit();
}
main()
{
int t;
GrafPtr savePort;
GrafPort XPort;
long WaitUntil;
pascal void ScrollUp(),ScrollDown();
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent,0);
InitWindows();
XCursor = GetResource('CURS',256);
InitCursor();
if(XCursor != nil){
HLock(XCursor);
SetCursor(*XCursor);
}
else{
SetCursor(&qd.arrow);
}
dragRect = qd.screenBits.bounds;
dragRect.top += 24;
dragRect.left +=4;
doneFlag = FALSE;
OpenPort(&XPort);
SetPort(&XPort);
PenPat(&qd.gray);
PaintRect(&XPort.portRect);
WaitUntil = TickCount() + 60L*8L;
while(WaitUntil > TickCount()){
if(Button()){
break;
}
}
ClosePort(&XPort);
theWindow = NewWindow
(nil,&qd.screenBits.bounds,"\000",TRUE,plainDBox,(Ptr)-1,FALSE,0L);
SetPort(theWindow);
DisposeWindow(theWindow);
SetUpMenus();
InitDialogs(DieGraceFully);
OpenPort(&srcport);
srcport.portBits.rowBytes = 32;
SetRect(&srcport.portBits.bounds,0,0,256,256);
srcport.portBits.baseAddr = NewPtr(256L*256L/8L);
if(srcport.portBits.baseAddr == nil){
SysError(dsMemFullErr);
}
SetPort(&srcport);
EraseRect(&srcport.portBits.bounds);
MoveTo(0,0);
PenSize(24,24);
LineTo(srcport.portBits.bounds.right,srcport.portBits.bounds.bottom);
MoveTo(srcport.portBits.bounds.right-12,srcport.portBits.bounds.top-12);
LineTo(srcport.portBits.bounds.left-12,srcport.portBits.bounds.bottom-12);
PenSize(1,1);
theWindow = GetNewWindow( 256, &wRecord, (Ptr)-1L );
SizeWindow(theWindow,256+15,256+15,TRUE);
ShowWindow(theWindow);
SetPort(theWindow);
theWindow->txFont = 2;
ResizePRect();
vScroll = GetNewControl( 256, theWindow);
hScroll = GetNewControl( 257, theWindow);
MoveScrollBars();
theOrigin.h = 0;
theOrigin.v = 0;
do { /* WELCOME TO THE MAIN EVENT LOOP. */
SystemTask();
if(XCursor != nil){
SetCursor(*XCursor);
}
else{
SetCursor(&qd.arrow);
}
GetNextEvent(everyEvent,&myEvent);
switch(myEvent.what) {
case mouseDown :
code = FindWindow(myEvent.where, &whichWindow);
switch(code) {
case inMenuBar :
DoCommand(MenuSelect(myEvent.where));
break;
case inSysWindow :
SystemClick(&myEvent,whichWindow);
break;
case inDrag :
DragWindow(whichWindow,myEvent.where,
&dragRect);
break;
case inGoAway :
if (TrackGoAway(whichWindow,myEvent.where))
doneFlag = TRUE;
break;
case inGrow :
if (whichWindow == FrontWindow())
GrowWnd(whichWindow);
else
SelectWindow(whichWindow);
break;
case inContent :
if (whichWindow != FrontWindow())
SelectWindow(whichWindow);
else {
GlobalToLocal(&myEvent.where);
if (!(PtInRect(myEvent.where,&pRect))){
MyControl = FindControl(myEvent.
where,
whichWindow,
&whichControl);
switch(MyControl) {
case inUpButton :
TrackControl(whichControl,
myEvent.where,
ScrollUp);
break;
case inDownButton :
TrackControl(whichControl,
myEvent.where,
ScrollDown);
break;
case inPageUp :
PageScroll(MyControl,-10);
break;
case inPageDown :
PageScroll(MyControl,10);
break;
case inThumb :
t = TrackControl(whichControl,
myEvent.where,
0L);
ScrollBits();
break;
}
}
}
break; /* in content */
}
break;
case activateEvt:
if (theWindow != (WindowPtr)myEvent.message)
break;
DrawGrowIcon(theWindow);
if (myEvent.modifiers&1) {
SetPort(theWindow);
ShowControl(vScroll);
ShowControl(hScroll);
}
else {
HideControl(vScroll);
HideControl(hScroll);
}
break;
case updateEvt :
GetPort(&savePort);
SetPort(theWindow);
BeginUpdate(theWindow);
EraseRect(&theWindow->portRect);
DrawWindow(theWindow);
EndUpdate(theWindow);
SetPort(savePort);
break;
}
}
while ( !doneFlag ) ;
exit (0);
}
/*
* An offscreen BitMap is used to hold the image last loaded into the
* program. On an update event, we CopyBits into the onscreen
* window.
*/
DrawStuff()
{
BackPat(&qd.white);
EraseRect(&srcport.portBits.bounds);
CopyBits(&srcport.portBits,&theWindow->portBits,&srcport.portBits.bounds,
&srcport.portBits.bounds,srcCopy,nil);
}
/*
* This section deals with input and output of 'PICT' files.
*/
long PICTCount;
short globalRef;
PicHandle PICTHand;
static Point SFWhere = { 0x0050, 0x0050 };
pascal void PutPICTData(dataPtr,byteCount)
Ptr dataPtr;
short byteCount;
{
long longCount;
longCount = (long)byteCount;
PICTCount += byteCount;
(void)FSWrite(globalRef,&longCount,dataPtr);
if(PICTHand != nil){
(**PICTHand).picSize = PICTCount;
}
}
SpoolOutPICTFile()
{
OSErr err;
short i;
long longCount,longZero;
Rect pFrame;
SFReply reply;
QDProcs myprocs;
GrafPtr tmpport;
SFPutFile(SFWhere,"\PSave as PICT file:","\PUntitled",nil,&reply);
if(reply.good){
GetPort(&tmpport);
SetPort(theWindow);
err = FSDelete(&reply.fName,reply.vRefNum);
err = Create(&reply.fName,reply.vRefNum,'????','PICT');
if(err != noErr){
return;
}
(void)FSOpen(&reply.fName,reply.vRefNum,&globalRef);
SetStdProcs(&myprocs);
theWindow->grafProcs = &myprocs;
myprocs.putPicProc = (Ptr)PutPICTData;
longZero = 0;
longCount = 4;
PICTCount = sizeof(Picture);
for(i=0;i++< (512/4 + sizeof(Picture));){
longCount = 4;
(void)FSWrite(globalRef,&longCount,&longZero);
}
(void)SetFPos(globalRef,fsFromStart,522L);
pFrame = srcport.portBits.bounds;
PICTHand = nil;
ClipRect(&pFrame);
PICTHand = OpenPicture(&pFrame);
DrawStuff();
ClosePicture();
(void)SetFPos(globalRef,fsFromStart,512L);
longCount = 10L;
(void)FSWrite(globalRef,&longCount,*PICTHand);
FSClose(globalRef);
theWindow->grafProcs = nil;
KillPicture(PICTHand);
SetPort(tmpport);
}
}
pascal void GetPICTData(dataPtr,byteCount)
Ptr dataPtr;
short byteCount;
{
long longCount;
short err;
longCount = (long)byteCount;
err = FSRead(globalRef,&longCount,dataPtr);
}
GetandDrawPICTFile()
{
SFReply reply;
GrafPtr tmpport;
QDProcs myprocs;
PicHandle PICTHand;
long longCount;
Rect pFrame;
static SFTypeList list = {'PICT'};
SFGetFile(SFWhere,0L,nil,1,list,0L,&reply);
if(reply.good && (FSOpen(&reply.fName,reply.vRefNum,&globalRef) == noErr)){
GetPort(&tmpport);
SetPort(theWindow);
SetWTitle(theWindow,&reply.fName);
InvalRect(&theWindow->portRect);
SetPort(&srcport);
SetStdProcs(&myprocs);
srcport.grafProcs = &myprocs;
myprocs.getPicProc = (Ptr)GetPICTData;
PICTHand = (PicHandle)NewHandle((long)sizeof(Picture));
SetFPos(globalRef,fsFromStart,512L);
longCount = 10L;
HLock(PICTHand);
(void)FSRead(globalRef,&longCount,*PICTHand);
srcport.portBits.bounds = pFrame = (**PICTHand).picFrame;
srcport.portRect = srcport.portBits.bounds;
if(srcport.portBits.baseAddr != nil){
DisposPtr(srcport.portBits.baseAddr);
}
srcport.portBits.baseAddr = NewPtr((long)((long)(pFrame.right-pFrame.left)*
(long)(pFrame.bottom-pFrame.top))/8L);
if(srcport.portBits.baseAddr == nil){
(void)FSClose(globalRef);
SysError(dsMemFullErr);
}
srcport.portBits.rowBytes = (pFrame.right-pFrame.left)/8;
ClipRect(&pFrame);
RectRgn(srcport.visRgn,&pFrame);
EraseRect(&pFrame);
HUnlock(PICTHand);
DrawPicture(PICTHand,&pFrame);
(void)FSClose(globalRef);
DisposHandle(PICTHand);
srcport.grafProcs = nil;
SizeWindowToImage();
}
}
SizeWindowToImage()
{
Rect pFrame;
pFrame = srcport.portBits.bounds;
SetPort(theWindow);
OffsetRect(&pFrame,-pFrame.left,-pFrame.top);
SetOrigin(0,0);
SetPt(&theOrigin,0,0);
SetCtlValue(vScroll,0);
SetCtlValue(hScroll,0);
pFrame.right += 15;
pFrame.bottom += 15;
LocalToGlobal(&pFrame.top);
LocalToGlobal(&pFrame.bottom);
SectRect(&pFrame,&dragRect,&pFrame);
SizeWindow(theWindow,pFrame.right-pFrame.left,pFrame.bottom-pFrame.top,TRUE);
MoveScrollBars();
ResizePRect();
}
/*
* This section deals with the input and output of X11 Bitmap files.
* For a change, stdio is used.
*/
/*
* Bit and byte order is reversed between QuickDraw BitMaps and
* X11 Bitmaps.
*/
char hextab[256];
void inithextab()
{
static int hextabinited = 0;
if (hextabinited == 0){
hextabinited = 1;
hextab[0] = '0'; hextab[1] = '8';
hextab[2] = '4'; hextab[3] = 'c';
hextab[4] = '2'; hextab[5] = 'a';
hextab[6] = '6'; hextab[7] = 'e';
hextab[8] = '1'; hextab[9] = '9';
hextab[10] = '5'; hextab[11] = 'd';
hextab[12] = '3'; hextab[13] = 'b';
hextab[14] = '7'; hextab[15] = 'f';
hextab['0'] = 0; hextab['1'] = 8;
hextab['2'] = 4; hextab['3'] = 12;
hextab['4'] = 2; hextab['5'] = 10;
hextab['6'] = 6; hextab['7'] = 14;
hextab['8'] = 1; hextab['9'] = 9;
hextab['A'] = 5; hextab['B'] = 13;
hextab['C'] = 3; hextab['D'] = 11;
hextab['E'] = 7; hextab['F'] = 15;
hextab['a'] = 5; hextab['b'] = 13;
hextab['c'] = 3; hextab['d'] = 11;
hextab['e'] = 7; hextab['f'] = 15;
}
}
getXBitmap()
{
SFReply frommac;
GrafPtr tmpport;
int width,height;
int c1,c2;
long nbytes;
char *ptr;
char ident[256];
static SFTypeList list = {'TEXT'};
SFGetFile(SFWhere,0L,nil,1,list,0L,&frommac);
if(frommac.good){
inithextab();
p2cstr(&frommac.fName);
SetVol(nil,frommac.vRefNum);
freopen(&frommac.fName,"r",stdin);
if(scanf("#define%s%d",ident,&width)!=2)return;
if(scanf(" #define%s%d",ident,&height)!=2)return;
ptr = ident;
while(*ptr){
if(ptr[0]=='_'){
ptr[0] = '\0';
break;
}
ptr++;
}
nbytes = ((long)width * (long)height)/8L;
if(srcport.portBits.baseAddr != nil){
DisposPtr(srcport.portBits.baseAddr);
}
ptr = srcport.portBits.baseAddr = NewPtr(nbytes);
if(ptr == nil){
SysError(dsMemFullErr);
}
srcport.portBits.rowBytes = width/8;
srcport.portBits.bounds.top = srcport.portBits.bounds.left = 0;
srcport.portBits.bounds.right = width;
srcport.portBits.bounds.bottom = height;
srcport.portRect = srcport.portBits.bounds;
while((c1=getchar())!=EOF){
if(c1 == 'x'){
c1 = getchar();
c2 = getchar();
*ptr++ = hextab[c1]+hextab[c2]*16;
}
}
GetPort(&tmpport);
SetPort(theWindow);
c2pstr(ident);
SetWTitle(theWindow,ident);
InvalRect(&theWindow->portRect);
SizeWindowToImage();
SetPort(tmpport);
}else{
SetRect(&srcport.portBits.bounds,0,0,200,200);
}
}
putXBitmap()
{
SFReply reply;
static SFTypeList list = {'TEXT'};
unsigned char *ptr;
long bytes,i;
FILE *fd;
SFPutFile(SFWhere,"\PSave as TEXT file:","\PUntitled",nil,&reply);
if(reply.good){
inithextab();
Create(&reply.fName,reply.vRefNum,'EDIT','TEXT');
p2cstr(&reply.fName);
SetVol(nil,reply.vRefNum);
fd = fopen(&reply.fName,"w");
ptr = (unsigned char *)&reply.fName;
while(*ptr){
if(*ptr == '.'){
*ptr = '\0';
break;
}
ptr++;
}
if(fd == NULL)return;
fprintf(fd,
"#define %s_width %d\n#define %s_height %d\nstatic char %s_bits[] = {\n ",
&reply.fName,
srcport.portBits.bounds.right - srcport.portBits.bounds.left,
&reply.fName,
srcport.portBits.bounds.bottom - srcport.portBits.bounds.top,
&reply.fName);
ptr = (unsigned char*)srcport.portBits.baseAddr;
bytes = GetPtrSize(ptr);
for(i=0L;i++<bytes;){
fprintf(fd,"0x%c%c",hextab[ptr[0]&0x0F],hextab[(ptr[0]>>4)&0x0F]);
if(i<bytes){
fprintf(fd,",");
}
if(i%15L == 0L){
fprintf(fd,"\n ");
}
ptr++;
}
fprintf(fd,"};\n");
fclose(fd);
}
}
MoveScrollBars()
{
HideControl(vScroll);
MoveControl(vScroll,theWindow->portRect.right-15,theWindow->
portRect.top-1);
SizeControl(vScroll,16,theWindow->portRect.bottom-theWindow->
portRect.top-13);
ShowControl(vScroll);
HideControl(hScroll);
MoveControl(hScroll,theWindow->portRect.left-1,theWindow->
portRect.bottom-15);
SizeControl(hScroll,theWindow->portRect.right-theWindow->
portRect.left-13,16);
ShowControl(hScroll);
}
ResizePRect()
{
pRect = theWindow->portRect;
pRect.right = pRect.right - 15;
pRect.bottom = pRect.bottom - 15;
}
GrowWnd(whichWindow)
WindowPtr whichWindow;
{
long longResult;
short height, width;
Rect tRect;
tRect = srcport.portBits.bounds;
if(tRect.right == 0)tRect.right = 84;
if(tRect.bottom == 0)tRect.bottom = 84;
OffsetRect(&tRect,16,16);
longResult = GrowWindow(whichWindow,myEvent.where,&tRect);
if ( longResult == 0 )
return;
height = longResult >> 16;
width = longResult;
/* add the old "scroll bar area" to the update region so it will */
/* be redrawn (for when the window is enlarged) */
tRect = whichWindow->portRect;
tRect.left = tRect.right - 16;
InvalRect(&tRect);
tRect = whichWindow->portRect;
tRect.top = tRect.bottom - 16;
InvalRect(&tRect);
/* now draw the newly sized window */
SizeWindow(whichWindow,width,height,TRUE);
MoveScrollBars();
ResizePRect();
/* add the new "scroll bar area" to the update region so it will
be redrawn (for when the window is made smaller) */
tRect = whichWindow->portRect;
tRect.left = tRect.right - 16;
InvalRect(&tRect);
tRect = whichWindow->portRect;
tRect.top = tRect.bottom - 16;
InvalRect(&tRect);
ScrollBits();
}
DrawWindow(whichWindow)
WindowPtr whichWindow;
{
Rect tRect;
ClipRect(&(theWindow->portRect));
DrawGrowIcon(theWindow);
DrawControls(theWindow);
/* now set up a clip area which excludes the scroll bars */
tRect = theWindow->portRect;
tRect.bottom = tRect.bottom - 15;
tRect.right = tRect.right - 15; /* Was 16 */
/* now compensate for any scrolling which has been done */
OffsetRect(&tRect, theOrigin.h, theOrigin.v);
ClipRect(&tRect);
/* change the origin to compensate for any scrolling */
SetOrigin(theOrigin.h, theOrigin.v);
DrawStuff();
SetOrigin(0,0);
ClipRect(&(theWindow->portRect)); /* reset the clip area */
}
ScrollBits()
{
Point oldOrigin;
int dh, dv, t1, t2;
Rect tRect;
oldOrigin = theOrigin;
t1 = (srcport.portBits.bounds.right - pRect.right);
t2 = (srcport.portBits.bounds.bottom - pRect.bottom);
/*
* The next step has to be done in long arithmetic, because a short int
* can overflow if the srcport portRect is large enough.
*/
theOrigin.h = ((long)t1 * (long)GetCtlValue(hScroll))/50L;
theOrigin.v = ((long)t2 * (long)GetCtlValue(vScroll))/50L;
dh = oldOrigin.h - theOrigin.h;
dv = oldOrigin.v - theOrigin.v;
theUpdateRgn = NewRgn();
ScrollRect( &pRect, dh, dv, theUpdateRgn);
/* have scrolled in junk... need to redraw */
SetOrigin(theOrigin.h, theOrigin.v);
OffsetRect(&(*theUpdateRgn)->rgnBBox,theOrigin.h, theOrigin.v);
ClipRect(&(*theUpdateRgn)->rgnBBox);
DrawStuff();
DisposeRgn(theUpdateRgn);
SetOrigin(0,0);
ClipRect(&(theWindow->portRect));
}
pascal void ScrollUp(whichControl,theCode)
ControlHandle whichControl;
short theCode;
{
if ( theCode == inUpButton ) {
SetCtlValue(whichControl,GetCtlValue(whichControl)-1);
ScrollBits();
}
}
pascal void ScrollDown(whichControl,theCode)
ControlHandle whichControl;
short theCode;
{
if ( theCode == inDownButton ) {
SetCtlValue(whichControl,GetCtlValue(whichControl)+1);
ScrollBits();
}
}
PageScroll(code,amount)
int code, amount;
{
Point myPt;
do {
GetMouse(&myPt);
if ( TestControl(whichControl,myPt) == code ) {
SetCtlValue(whichControl,GetCtlValue(whichControl)+amount);
ScrollBits();
}
}
while (StillDown());
}
SetUpMenus()
{
int i;
InitMenus();
myMenu[0] = GetMenu(appleMenu);
AddResMenu(myMenu[0],'DRVR'); /* desk accesories */
myMenu[1] = GetMenu(fileMenu);
myMenu[2] = GetMenu(editMenu);
for ( i = 0; i < lastMenu; i++ )
InsertMenu(myMenu[i],0);
DrawMenuBar();
}
DoCommand(mResult)
unsigned long mResult;
{
char name[30];
short theMenu, theItem;
theMenu = mResult >> 16;
theItem = mResult;
switch (theMenu) {
case appleMenu :
if(theItem == 1){
Alert(128,nil);
}else{
GetItem(myMenu[0],theItem,name);
OpenDeskAcc(name);
}
break;
case fileMenu :
switch(theItem){
case openX:
getXBitmap();
break;
case saveX:
putXBitmap();
break;
case openPICT:
GetandDrawPICTFile();
break;
case savePICT:
SpoolOutPICTFile();
break;
case Quit:
doneFlag = TRUE;
break;
default:
break;
}
case editMenu:
(void)SystemEdit(theItem-1);
break;
}
HiliteMenu(0);
}